import asyncio
import websockets
import json
from tool.config import config as tool_config
import pyttsx3

config = tool_config.get_config("config.toml")

DEFAULT_API_TOKEN = config["FISHSPEECH"]["DEFAULT_API_TOKEN"]
DEFAULT_MODEL_ID = config["FISHSPEECH"]["DEFAULT_MODEL_ID"]
DEFAULT_AUDIO_FORMAT = config["FISHSPEECH"]["DEFAULT_AUDIO_FORMAT"]
DEFAULT_TTS_VERSION = config["FISHSPEECH"]["DEFAULT_TTS_VERSION"]
FISH_SPEECH_URL = config["FISHSPEECH"]["FISH_SPEECH_URL"]

def fallback_tts(text: str, output_file: str) -> str:
    """
    使用 pyttsx3 进行本地 TTS 兜底语音合成。
    """
    engine = pyttsx3.init()
    engine.setProperty('rate', 160)  # 可调语速
    engine.save_to_file(text, output_file)
    engine.runAndWait()
    return output_file

async def _run_websocket_tts(text: str,
                              api_token: str,
                              model_id: str,
                              output_file: str,
                              audio_format: str,
                              tts_version: str) -> str:
    ws_url = f"{FISH_SPEECH_URL}{api_token}"
    audio_data = bytearray()

    async with websockets.connect(ws_url) as websocket:
        await websocket.send(json.dumps({
            "event": "start",
            "token": api_token,
            "request": {
                "reference_id": model_id,
                "format": audio_format,
                "version": tts_version,
                "latency": "normal"
            }
        }))

        while True:
            message = await websocket.recv()
            print(f"Received message: {len(message)}\r")  # 调试输出，查看接收到的消息
            if isinstance(message, bytes):
                audio_data.extend(message)
            else:
                data = json.loads(message)
                event = data.get("event")
                if event == "ready":
                    await websocket.send(json.dumps({
                        "event": "text",
                        "text": text
                    }))
                elif event == "done":
                    with open(output_file, "wb") as f:
                        f.write(audio_data)
                    return output_file
                elif event == "error":
                    raise RuntimeError(data.get("message", "Unknown error"))

def synthesize_speech(text: str,
                      output_file: str = "output.mp3",
                      api_token: str = DEFAULT_API_TOKEN,
                      model_id: str = DEFAULT_MODEL_ID,
                      audio_format: str = DEFAULT_AUDIO_FORMAT,
                      tts_version: str = DEFAULT_TTS_VERSION) -> str:
    """
    首选使用 FishSpeech WebSocket TTS 进行语音合成，如失败则回退到本地 pyttsx3。
    """
    coro = _run_websocket_tts(
        text=text,
        api_token=api_token,
        model_id=model_id,
        output_file=output_file,
        audio_format=audio_format,
        tts_version=tts_version
    )
    try:
        return asyncio.run(coro)
    except Exception as e:
        print(f"[FishSpeech 合成失败] {e}，切换到本地 pyttsx3...")
        return fallback_tts(text, output_file)